home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / PIPE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-30  |  6.8 KB  |  345 lines

  1. #ifdef UNIX
  2. #ifdef _lint
  3. int
  4. dopipe (int argc, char *argv[], void *p OPTIONAL)
  5. {
  6.     return 0;
  7. }
  8. #else
  9.  
  10. #include "global.h"
  11. #ifdef PIPECMD
  12. #include <signal.h>
  13. #include "proc.h"
  14. #include "hardware.h"
  15. #include "session.h"
  16. extern int keywait (const char *prompt,int flush);
  17. extern int sockblock (int s,int value);
  18. extern int recvchar (int s);
  19. #define setflush j_setflush
  20. extern int setflush (int s,int c);
  21. extern int socketalive (int s);
  22. extern int dup (int oldfd);
  23. #include <sys/wait.h>
  24. #include <sys/time.h>
  25.  
  26. #if !defined(_lint)
  27. static char rcsid[] OPTIONAL = "$Id: pipe.c,v 1.17 1997/07/31 00:44:20 root Exp root $";
  28. #endif
  29.  
  30. #ifdef SOCK_STREAM
  31. #undef SOCK_STREAM
  32. #endif
  33. #include <sys/socket.h>
  34.  
  35. #ifdef socketpair
  36. #undef socketpair
  37. #endif
  38.  
  39. static void sig_pipe(int);
  40. static int s_pipe(int fd[2]);
  41. int dopipe (int argc,char *argv[],void *p);
  42. static void pipe_io(int fd, FILE *fpin, FILE *fpout);
  43. extern int dup2(int oldfd, int newfd);
  44.  
  45. #define STDIN_FILENO 0
  46. #define STDOUT_FILENO 1
  47. #ifndef _lint
  48. #define STDERR_FILENO 2
  49. #endif
  50. #define MAXLINE 512
  51.  
  52. #define SOCK_NOTXBLOCK  1
  53. #define SOCK_NORXBLOCK  2
  54. #ifndef _lint
  55. #define SOCK_BINARY 0
  56. #endif
  57.  
  58. static const char strCR[] = "pipe: %s\n";
  59. static int Aborted = 0;
  60.  
  61.  
  62. static void
  63. pipe_io (int fd, FILE *fpin, FILE *fpout)
  64. {
  65. int n;
  66. char line[MAXLINE];
  67. int retval;
  68. int done = 0;
  69. int oldblock = 0;
  70. int oldblock2 = 0;
  71. int oldflush = 0;
  72. int oldflush2 = 0;
  73. #if 0
  74. int oldmode = 0;
  75. int oldmode2 = 0;
  76. int edit, echo;
  77. #endif
  78. static fd_set fdr;
  79. static struct timeval tv;
  80. struct timeval *tvp;
  81. int fd2;
  82.  
  83.     if (fpin == stdin)    {
  84. #if 0
  85.         if (Current->s == -1)
  86.             Current->s = Curproc->input;
  87. #endif
  88.         oldblock = sockblock(Curproc->input,SOCK_NORXBLOCK);
  89.         oldblock2 = sockblock(Curproc->output,SOCK_NOTXBLOCK);
  90.         oldflush = setflush (Curproc->input, -1);
  91.         oldflush2 = setflush (Curproc->output, -1);
  92. #if 0
  93.         oldmode = sockmode(Curproc->input,SOCK_BINARY);
  94.         oldmode2 = sockmode(Curproc->output,SOCK_BINARY);
  95.         echo = Current->ttystate.echo;
  96.         edit = Current->ttystate.edit;
  97.             Current->ttystate.echo = Current->ttystate.edit = 0;
  98. #endif
  99.     }
  100.  
  101.  
  102.     fd2 = dup (fd);
  103.     tvp = &tv;
  104.  
  105.     do    {
  106.         if (fpin == stdin)    {
  107.             retval = 0;
  108.             line[1] = 0;
  109. #if 1
  110.             retval = recvchar(Curproc->input);
  111. #else
  112.             retval = rrecvchar(Curproc->input);
  113. #endif
  114.             if (retval == EOF)    {
  115.                 if (errno == EWOULDBLOCK)    {
  116.                     line[0] = 0;
  117.                     retval = 0;
  118.                 } else
  119.                     Aborted = retval;
  120.             } else
  121.                 line[0] = (char) retval;
  122.         } else
  123.             retval = (int) fgets (line, MAXLINE, fpin);
  124.         if (Aborted || (fpin == stdin && retval == EOF) || (fpin != stdin && !retval)) {
  125.             done = 1;
  126.             continue;
  127.         }
  128.  
  129. #if 0
  130.         if (!socketalive (Current->s))    {
  131. #else
  132.         if (!socketalive (Curproc->input))    {
  133. #endif
  134.             done = 1;
  135.             continue;
  136.         }
  137.  
  138.         kwait (NULL);
  139.  
  140.         n = (int) strlen (line);
  141.         if (n && write (fd, line, (unsigned int) n) != n)    {
  142.             tprintf (strCR, "write error");
  143.             break;
  144.         }
  145.         if (Aborted)
  146.             continue;
  147.  
  148.         kpause (20);
  149.  
  150.         tv.tv_sec = tv.tv_usec = 0;
  151. #ifndef _lint
  152.         FD_ZERO(&fdr);
  153.         FD_SET(fd2, &fdr);
  154. #endif
  155.         if (select(fd2 + 1, &fdr, 0, 0, tvp))    {
  156.             if ((n = read (fd2, line, MAXLINE)) < 0)    {
  157.                 tprintf (strCR, "read error");
  158.                 break;
  159.             }
  160.             if (Aborted)
  161.                 continue;
  162.             if (!n)
  163.                 continue;
  164.             line[n] = 0;
  165.             if (fpout == stdout)
  166.                 tputs(line);
  167.             else
  168.                 fputs (line, fpout);
  169.         }
  170.         kwait (NULL);
  171.     } while (!done && !Aborted);
  172.  
  173.     close (fd2);
  174.  
  175.     if (fpin == stdin)    {
  176.         (void) sockblock(Curproc->input,oldblock);
  177.         (void) sockblock(Curproc->output,oldblock2);
  178.         (void) setflush(Curproc->input,oldflush);
  179.         (void) setflush(Curproc->output,oldflush2);
  180. #if 0
  181.         sockmode(Curproc->input,oldmode);
  182.         sockmode(Curproc->output,oldmode2);
  183.         Current->ttystate.echo = echo;
  184.         Current->ttystate.edit = edit;
  185. #endif
  186.     }
  187. }
  188.  
  189.  
  190. static void
  191. pipe_cmd (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
  192. {
  193. int fd[2];
  194. FILE *fpin;
  195. FILE *fpout;
  196. struct session *sp = NULLSESSION;
  197. int usesession = 0;
  198. #if 0
  199. pid_t pid;
  200. #endif
  201.     /* Use a session if this comes from console */
  202.     if(Curproc->input == Command->input) {
  203.         usesession = 1;
  204.         if((sp = newsession(argv[1],MORE,0)) == NULLSESSION)    {
  205.             return;
  206.         }
  207.     }
  208.  
  209.     if (signal (SIGPIPE, sig_pipe) == SIG_ERR)    {
  210.         tprintf (strCR,"signal error");
  211.         return;
  212.     }
  213.  
  214.     if (s_pipe (fd) < 0)    {
  215.         tprintf (strCR, "pipe error");
  216.         return;
  217.     }
  218.  
  219. /*    fpin = (FILE *)p;    */
  220. #if 0
  221.     if (p)    {
  222.         fpin =  ((FILE **)p)[0];
  223.         fpout = ((FILE **)p)[1];
  224.     } else    {
  225. #endif
  226.     fpin = stdin;
  227.     fpout = stdout;
  228. #if 0
  229.     }
  230. #endif
  231.     
  232.     Aborted = 0;
  233.  
  234. #if 0
  235.     switch (pid = fork())    {
  236. #else
  237.     switch (fork())    {
  238. #endif
  239.         case -1:    tprintf (strCR,"fork error");
  240.                 return;
  241.  
  242.         case 0:        /* child */
  243.             close (fd[0]);
  244.             if (fd[1] != STDIN_FILENO)    {
  245.                 if (dup2 (fd[1], STDIN_FILENO) != STDIN_FILENO)    {
  246.                     tprintf(strCR, "dup2 error to stdin");
  247.                     return;
  248.                 }
  249.             }
  250.             if (fd[1] != STDOUT_FILENO)    {
  251.                 if (dup2 (fd[1], STDOUT_FILENO) != STDOUT_FILENO)    {
  252.                     tprintf(strCR, "dup2 error to stdout");
  253.                     return;
  254.                 }
  255.             }
  256.             if (execvp (argv[0], (char * const *) argv) < 0)    {
  257.                 tprintf(strCR, "execvp error");
  258.                 return;
  259.             }
  260.             break;
  261.  
  262.         default:    /* parent */
  263.             close (fd[1]);
  264.             pipe_io(fd[0], fpin, fpout);
  265.             close (fd[0]);
  266.             (void) wait (NULL);
  267.             (void) signal (SIGPIPE, SIG_DFL);
  268.  
  269.             if (usesession)    {
  270.                 (void) keywait(NULLCHAR,1);
  271.                 freesession(sp);
  272.             }
  273.             return;
  274.     }
  275. }
  276.  
  277.  
  278. static void
  279. sig_pipe (int signo OPTIONAL)
  280. {
  281.     Aborted = 1;
  282. }
  283.  
  284.  
  285. static int
  286. s_pipe (int fd[2])
  287. {
  288.     return (socketpair (AF_UNIX, SOCK_STREAM, 0, fd));
  289. }
  290.  
  291.  
  292. int
  293. dopipe (argc, argv, p)
  294. int argc;
  295. char *argv[];
  296. void *p OPTIONAL;
  297. {
  298. char **pargv;
  299. int i;
  300. FILE *fps[2];
  301.  
  302.     fps[0] = stdin;
  303.     fps[1] = stdout;
  304.     if (!--argc)
  305.         return 0;
  306.     argv++;                /*lint !e608 */
  307.     if (!strnicmp(argv[0], "-f", 2))    {
  308.         fps[0] = fopen (&argv[0][2], "r");
  309.         if (fps[0] == NULLFILE)    {
  310.             tprintf ("Sorry, can't open file '%s'\n", &argv[0][2]);
  311.             return 0;
  312.         }
  313.         if (!--argc)
  314.             return 0;
  315.         argv++;            /*lint !e608 */
  316.     }
  317.     if (!strnicmp(argv[0], "-t", 2))    {
  318.         fps[1] = fopen (&argv[0][2], "w");
  319.         if (fps[1] == NULLFILE)    {
  320.             tprintf ("Sorry, can't open file '%s'\n", &argv[0][2]);
  321.             return 0;
  322.         }
  323.         if (!--argc)
  324.             return 0;
  325.         argv++;            /*lint !e608 */
  326.     }
  327.     if(Curproc->input == Command->input) {
  328.         /* Make private copy of argv and args,
  329.          * spawn off subprocess and return.
  330.          */
  331.         pargv = (char **)callocw((size_t)argc,sizeof(char *));
  332.         for(i = 0; i < argc; i++)
  333.             pargv[i] = strdup(argv[i]);
  334.         pargv[i] = NULL;
  335.             (void) newproc("pipe",512,(void (*)(int,void *,void *))pipe_cmd,argc,(void *)pargv,(void *)fps,1);
  336.     } else
  337.         pipe_cmd (argc, argv, (void *)fps);
  338.     return 0;
  339. }
  340.  
  341. #endif    /* PIPECMD */
  342. #endif  /* _lint */
  343. #endif     /* UNIX */
  344.  
  345.